#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
selenium基类
本文件存放了selenium基类的封装方法
"""
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException, \
    ElementNotInteractableException

from common.readconfig import ini
from config.conf import cm
from utils.times import sleep
from utils.logger import log


class WebPage(object):
    """封装selenium基类的好处：
       1.应对网络，控件，元素定位等复杂情况
       2.内置显式等待或一定的条件语句，可以构建一个稳定的方法
       3.把selenium方法封装起来，有于平时的代码维护
    """

    def __init__(self, driver):
        self.driver = driver
        self.timeout = 10
        self.wait = WebDriverWait(self.driver, self.timeout)

    def get_url(self, url):
        """打开网址并验证"""
        self.driver.maximize_window()
        self.driver.set_page_load_timeout(30)
        try:
            self.driver.get(url)
            self.driver.implicitly_wait(5)
            log.info("打开网页：%s" % url)
        except TimeoutException:
            raise TimeoutException("打开%s超时请检查网络或网址服务器" % url)

    def find(self, locator):
        return self.driver.find_element(*locator)

    def finds(self, locator):
        return self.driver.find_elements(*locator)

    def wait(self, timeout, condition, message=""):
        WebDriverWait(self.driver, timeout).until(condition, message)

    @staticmethod
    def element_locator(func, locator):
        """元素定位器"""
        name, value = locator
        return func(cm.LOCATE_MODE[name], value)

    # def find_element(self, locator):
    #     """寻找单个元素"""
    #     # print("1111", locator,"1111")
    #     return WebPage.element_locator(lambda *args: self.wait.until(
    #         EC.presence_of_element_located(args)), locator)
    #
    # def find_elements(self, locator):
    #     """查找多个相同的元素"""
    #     return WebPage.element_locator(lambda *args: self.wait.until(
    #         EC.presence_of_all_elements_located(args)), locator)

    def elements_num(self, locator):
        """获取相同元素的个数"""
        number = len(self.find_elements(locator))
        log.info("相同元素：{}".format((locator, number)))
        return number

    def input_text(self, locator, txt):
        """输入(输入前先清空)"""
        sleep(0.5)
        ele = self.find_element(locator)
        ele.clear()
        ele.send_keys(txt)
        log.info("输入文本：{}".format(txt))

    def click_element(self, locator):
        """点击"""
        element = self.find(locator)
        try:
            element.click()
        except ElementClickInterceptedException:
            self.driver.execute_script("arguments[0].click();", element)
        except ElementNotInteractableException:
            self.driver.execute_script("arguments[0].scrollIntoView(false);", element)
            WebDriverWait(self.driver, 5).until(EC.element_to_be_clickable(locator)).click()
        # try:
        #     self.find_element(locator).click()
        # except Exception as E:
        #     # 无法点击时，比如拦截，用下面的方法
        #     print(E)
        #     webdriver.ActionChains(self.driver).move_to_element(locator).click(locator).perform()
        # sleep()
        # log.info("点击元素：{}".format(locator))

    def is_clicks(self, locator):
        elements = self.find_elements(locator)
        for e in elements:
            e.click()
            sleep()
            # log.info("点击元素：{}".format(locator))
            self.driver.get(ini.url)
            sleep(3)

    def element_text(self, locator):
        """获取当前的text"""
        _text = self.find_element(locator).text
        log.info("获取文本：{}".format(_text))
        return _text

    # 属性方法，可用class.name进行调用，不用加括号()
    @property
    def get_source(self):
        """获取页面源代码"""
        return self.driver.page_source

    def refresh(self):
        """刷新页面F5"""
        self.driver.refresh()
        self.driver.implicitly_wait(30)